package edu.fim.presentation.view;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.swing.AbstractButton;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;

import edu.fim.core.exception.ServiceException;
import edu.fim.presentation.controller.ConsumerController;
import edu.fim.presentation.controller.MealController;
import edu.fim.presentation.model.bean.Food;
import edu.fim.presentation.model.bean.Meal;
import edu.fim.presentation.model.bean.Portion;

public class AddMealForm extends AbstractForm {
	private static final long serialVersionUID = 8068910800995775741L;

	private ConsumerController consumerController;
	private MealController mealController;

	private JComboBox<Food> foodComboBox;
	private JSpinner quantitySpinner;
	private JSpinner hoursSpinner;
	private JSpinner minutesSpinner;

	public AddMealForm(String title, ConsumerController consumerController,
			MealController mealController) {
		super(title);
		this.consumerController = consumerController;
		this.mealController = mealController;
		initialize();
		update();
	}

	public void update() {
		pack();
	}

	protected void initializeDynamicComponents() {
		initializeFoodComboBox();
		quantitySpinner = new JSpinner(new SpinnerNumberModel(0, 0, Integer.MAX_VALUE, 0.5));
		hoursSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 23, 1));
		minutesSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 59, 1));
	}

	protected void buildLayout() {
		getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
		getContentPane().add(createDataContainer());
		getContentPane().add(createButtonContainer());
	}

	private Component createDataContainer() {
		Container container = new Container();
		container.setLayout(new GridLayout(3, 2, 5, 5));
		container.add(new JLabel("Food:"));
		container.add(foodComboBox);
		container.add(new JLabel("Quantity:"));
		container.add(quantitySpinner);
		container.add(new JLabel("Time:"));
		container.add(createTimeField());
		return container;
	}

	private Component createTimeField() {
		Container container = new Container();
		container.setLayout(new FlowLayout());
		container.add(hoursSpinner);
		container.add(new JLabel(":"));
		container.add(minutesSpinner);
		return container;
	}

	private Component createButtonContainer() {
		Container container = new Container();
		container.setLayout(new FlowLayout());
		container.add(createConfirmButton());
		container.add(createCancelButton());
		return container;
	}

	private void initializeFoodComboBox() {
		foodComboBox = new JComboBox<Food>();
		foodComboBox.setMinimumSize(new Dimension(150, 20));
		foodComboBox.setPreferredSize(new Dimension(150, 20));
		foodComboBox.setMaximumSize(new Dimension(150, 20));
		updateFoodComboBox();
	}

	private void updateFoodComboBox() {
		foodComboBox.removeAllItems();
		for (Food food : consumerController.getCurrentConsumer()
				.getPreferences()) {
			foodComboBox.addItem(food);
		}
	}

	private Component createConfirmButton() {
		AbstractButton button = new JButton("Add");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				confirmButtonActionPerformed();
			}
		});
		return button;
	}

	private Component createCancelButton() {
		AbstractButton button = new JButton("Cancel");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				cancelButtonActionPerformed();
			}
		});
		return button;
	}

	private void confirmButtonActionPerformed() {
		 Food food = (Food) foodComboBox.getSelectedItem();
		 Calendar date = new GregorianCalendar();
		 date.set(Calendar.HOUR, (Integer) hoursSpinner.getValue());
		 date.set(Calendar.MINUTE, (Integer) minutesSpinner.getValue());
		 Meal meal = new Meal(consumerController.getCurrentConsumer(), date);
		 Portion portion = new Portion(food, (Double) quantitySpinner.getValue(), meal);
		 meal.add(portion);
		 mealController.add(meal);
		 try {
			 mealController.insert(meal);
			 showMessage("Meal added successfully.");
		 } catch (ServiceException e) {
			 e.printStackTrace();
			 showMessage("Could not add Meal.");
		 }
	}

	private void cancelButtonActionPerformed() {
		this.setVisible(false);
	}
}